package reflect;

import javax.swing.plaf.PanelUI;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectTest {

    //获取类对象的四种方式
    public static void main(String[] args) throws Exception {

        test7();
    }

    public static void test7() throws Exception {

        //获取类对象
        Class<Prodcut> prodcutClass = Prodcut.class;
        Constructor<Prodcut> declaredConstructor = prodcutClass.getDeclaredConstructor();

        //修改构造函数访问权限
        declaredConstructor.setAccessible(true);
        Prodcut prodcut = declaredConstructor.newInstance();
        System.out.println(prodcut.toString());

        //获取属性
        Field id = prodcutClass.getDeclaredField("id");
        Field name = prodcutClass.getDeclaredField("name");
        id.setAccessible(true);
        name.setAccessible(true);

        //设置指定对象的属性值
        id.set(prodcut, 10);
        name.set(prodcut, "test");
        System.out.println(prodcut.toString());
    }

        public static void test6() throws Exception {

        Class<User> userClass = User.class;
        Constructor<User> declaredConstructor = userClass.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        User user = declaredConstructor.newInstance();
        user.setName("小张");
        user.setAge(18);
        System.out.println(user.toString());
    }


        public static void test5() throws Exception {

        //获取类对象
        Class<User> userClass = User.class;

        //获取的public的属性，当前类和父类
        Field[] fields = userClass.getFields();
        for (Field field : fields) {
            System.out.println("修饰符："+field.getModifiers()+",属性类型："+field.getType().getName()
                    +",属性名:"+field.getName());
        }

        System.out.println("======");
        //获取当前类的全部属性，权限修饰不影响
        Field[] declaredFields = userClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println("修饰符："+field.getModifiers()+",属性类型："+field.getType().getName()
                    +",属性名:"+field.getName());
        }
    }

    public static void test4() throws Exception {

        //获取类对象
        Class<User> userClass = User.class;
        //获取当前类和父类中声明的方法，需要时public类型
        Method[] methods = userClass.getMethods();
        for (Method method : methods) {
            System.out.println("修饰符："+method.getModifiers()+",返回符："+method.getReturnType()
            +",method:"+method);
        }

        System.out.println("======");
        //获取当前类的全部方法，不管修饰符
        Method[] declaredMethods = userClass.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println("修饰符："+method.getModifiers()+",返回符："+method.getReturnType()
                    +",method:"+method);
        }
    }

    public static void test3 () throws Exception {

        Class<User> userClass = User.class;

        //获取指定构造器
        Constructor<User> constructor = userClass.getConstructor(int.class, String.class);
        User user= constructor.newInstance(21, "老张");
        System.out.println(user.toString());
    }

    public static void test2() throws Exception {

        Class<User> userClass = User.class;

        //获取空构造函数，并且创建对象
        //如果获取的是private类型的构造函数，则不能直接new对象
        User user = userClass.getDeclaredConstructor().newInstance();
        user.setAge(11);
        user.setName("小张");
        System.out.println(user.toString());
    }

    public static void  test1() throws Exception {
        //通过类名获取
        Class<User> userClass1 = User.class;

        //通过对象获取
        User user = new User(1);
        Class<? extends User> userClass2 = user.getClass();

        //通过全限类名
        Class<?> userClass3 = Class.forName("reflect.User");

        //通过类加载器
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        Class<?> userClass4 = classLoader.loadClass("reflect.User");

        System.out.println(userClass1);
        System.out.println(userClass2);
        System.out.println(userClass3);
        System.out.println(userClass4);
        System.out.println("======");

        System.out.println("getSimpleName =" + userClass1.getSimpleName());
        System.out.println("getName = " + userClass1.getName());
        System.out.println("======");


        Constructor<User> declaredConstructor = userClass1.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor.getName()+","+declaredConstructor.getParameterCount());
        System.out.println("======");


        Constructor<?>[] declaredConstructors = userClass1.getDeclaredConstructors();
        for (Constructor constructor: declaredConstructors){
            System.out.println(constructor.getName()+","+constructor.getParameterCount());
        }
        System.out.println("======");

        Constructor<?>[] constructors = userClass1.getConstructors();
        for (Constructor constructor: constructors){
            System.out.println(constructor.getName()+","+constructor.getParameterCount());
        }
    }
}
